/**
 * 
 */
package game.gamestorage.texas.db.estimation;

import game.gamestorage.texas.db.SQLHandler;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;

/**
 * This class is the "db-side" part of the mapping form database to Java</br>
 * Responsable for reading the db
 * 
 * @author Witthold/Korol
 * 
 * TODO use allTime methods for higher performance - eval that
 */
public class GetterQueryExecution {

	/** SQLHandler initializes ConnectionManager */
	protected static SQLHandler h = new SQLHandler();


	/**
	 * @category getCommonsOfCompetition<br>
	 * @param timestamp as unix timestamp
	 * @return int[] of competition_ids newer than timestamp && same gamedef like newest
	 */
	public static int[] getCompetitionIds(long timestamp) {

		int[] arr = h.sqlGetIntArrayOnePerRow(GetterQuery.getCompetitionIds(timestamp));

		return arr;
	}


	/**
	 * @category getCommonsOfCompetition<br>
	 * @param gamedef_id - already generated by db
	 * @return int[] of competition_ids newer than timestamp && same gamedef like newest
	 */
	public static int[] getCompetitionIds(int gamedef_id) {

		int[] arr = h.sqlGetIntArrayOnePerRow(GetterQuery.getCompetitionIds(gamedef_id));

		return arr;
	}


	/**
	 * @category getCommonsOfCompetition<br>
	 * @param gamedef_id - already generated by db
	 * @param timestamp as unix timestamp
	 * @return int[] of competition_ids newer than timestamp && same gamedef like current
	 */
	public static int[] getCompetitionIds(int gamedef_id, long timestamp) {

		int[] arr = h.sqlGetIntArrayOnePerRow(GetterQuery.getCompetitionIds(gamedef_id, timestamp));

		return arr;
	}


	/**
	 * @category getCommonsOfCompetition<br>
	 * @return int competition.id
	 */
	public static int getLatestCompetitionId() {

		int i = h.sqlGetInt(GetterQuery.getLatestCompetitionId());

		return i;
	}


	/**
	 * @category getCommonsOfCompetition<br>
	 * @return int competition.id
	 */
	public static int getLatestHandId() {

		int i = h.sqlGetInt(GetterQuery.getLatestHandId());

		return i;
	}


	/**
	 * @category getCommonsOfCompetition<br>
	 * @param competition_id already generated by db
	 * @return HashMap of Integer, String: player.id, player.alias
	 */
	public static HashMap<Integer, String> getPlayersInCompetition(int competition_id) {

		HashMap<Integer, String> hm_is = h.sqlGetHashMapIntString(GetterQuery.getPlayersInCompetition(competition_id));

		return hm_is;
	}


	/**
	 * @category getCommonsOfCompetition<br>
	 * @param competition_id already generated by db
	 * @return HashMap of String, Integer: player.alias, player.id
	 */
	public static HashMap<String, Integer> getPlayersInCompetitionSI(int competition_id) {

		HashMap<String, Integer> hm_si = h.sqlGetHashMapStringInt(GetterQuery.getPlayersInCompetitionSI(competition_id));

		return hm_si;
	}


	/**
	 * @category getCommonsOfCompetition<br>
	 * @param competition_id already generated by db
	 * @return ArrayList of int[]: player_id, cash_init, rank
	 */
	protected static ArrayList<int[]> getCompetitionPlayerMaps(int competition_id) {

		ArrayList<int[]> al = h.sqlGetIntArrayListMultiPerRow(GetterQuery.getCompetitionPlayerMaps(competition_id), 3);

		return al;
	}


	/**
	 * @category getStatsForSHC<br>
	 * @param player_id already generated by db
	 * @param competition_id already generated by db
	 * @param lastEvaledHandId already generated by db
	 * @return ArrayList of int[]: <br>
	 *         hand_player_map for EnemyCardsOpen with:<br>
	 *         hand_player_map.id, hand_player_map.position, hand_player_map.cash_init, hand_player_map.cash_delta, hand_player_map.hand_id
	 */
	protected static ArrayList<int[]> getHandPlayerMapsWhereEnemyCardsOpen(int player_id, int competition_id, int lastEvaledHandId) {

		ArrayList<int[]> al = h.sqlGetIntArrayListMultiPerRow(
				GetterQuery.getHandPlayerMapWhereEnemyCardsOpenPerComp(player_id, competition_id, lastEvaledHandId), 5);

		return al;
	}


	/**
	 * @category getStatsForSHC<br>
	 * @param hand_id already generated by db
	 * @return numActivePlayers at hand
	 */
	protected static int getNumActivePlayers(int hand_id) {

		int numActivePlayers = h.sqlGetInt(GetterQuery.getNumActivePlayers(hand_id));

		return numActivePlayers;
	}
	
	/**
	 * @category getStatsForSHC<br>
	 * @param hand_id already generated by db
	 * @return numActivePlayers at hand
	 */
	protected static int getCallSize(long betId, long playerId, long handId) {

		int currentBet = h.sqlGetInt(GetterQuery.getCurrentBet(betId, playerId, handId));
		int highestBet = h.sqlGetInt(GetterQuery.getHighestBet(betId, handId));
		int callsize = highestBet - currentBet;

		return callsize;
	}


	/**
	 * @category getStatsForSHC<br>
	 * @param hand_player_map_id already generated by db
	 * @return int[] EnemyCards
	 */
	protected static int[] getHoleCards(int hand_player_map_id) {

		int[] cards = h.sqlGetIntArrayOnePerRow(GetterQuery.getHoleCards(hand_player_map_id));

		return cards;
	}
	
	/**
	 * @category getStatsForSHC<br>
	 * @param hand_player_map_id already generated by db
	 * @return int[] EnemyCards
	 */
	protected static int[][] getAllHoleCardsOfHand(int hand_id) {
		int[][] cards = h.sqlGetIntArrayMultiPerRow(GetterQuery.getAllHoleCardsOfHand(hand_id), 2);
		return cards;
	}
	
	/**
	 * @category getStatsForFlop<br>
	 */
	protected static int[] getBoardCards(int round_id) {

		int[] cards = h.sqlGetIntArrayOnePerRow(GetterQuery.getBoardCards(round_id));

		return cards;
	}


	/**
	 * @category getStatsForSHC<br>
	 * @param player_id already generated by db
	 * @param hand_id already generated by db
	 * @return long[] BetOfFirstAction with:<br>
	 *         id, action, betsize, potsize, timestamp, round_id
	 */
	protected static long[] getBetOfFirstAction(int player_id, int hand_id) {

		ArrayList<long[]> result = h.sqlGetLongArrayListMultiPerRow(GetterQuery.getFirstBetOfRound(player_id, hand_id), 6);

		long[] bet = result.get(0);

		return bet;
	}
	
	
	/**
	 * @category getStatsForSHC<br>
	 * @param player_id already generated by db
	 * @param competition_id already generated by db
	 * @param lastEvaledHandId already generated by db
	 * @return ArrayList of long[] firstBetsOfRound with:<br>
	 *         bet.round_id, MIN(bet.id), bet.action, bet.betsize, bet.potsize, bet.timestamp, bet.round_id
	 */
	protected static ArrayList<long[]> getFirstBetsOfRound(int player_id, int competition_id, int lastEvaledHandId) {

		ArrayList<long[]> result = h.sqlGetLongArrayListMultiPerRow(GetterQuery.getFirstBetsOfRound(player_id, competition_id, lastEvaledHandId), 7);		

		return result;
	}
	
	/**
	 * @category getStatsForFlop<br>
	 * @param player_id already generated by db
	 * @param competition_id already generated by db
	 * @param lastEvaledHandId already generated by db
	 * @return ArrayList of long[] firstBetsOfRound with:<br>
	 *         bet.round_id, MIN(bet.id), bet.action, bet.betsize, bet.potsize, bet.timestamp, bet.round_id
	 */
	protected static ArrayList<long[]> getFlopBetsOfRound(int player_id, int competition_id, int lastEvaledHandId) {

		ArrayList<long[]> result = h.sqlGetLongArrayListMultiPerRow(GetterQuery.getFlopBetsOfRound(player_id, competition_id, lastEvaledHandId), 7);		

		return result;
	}
	
	
	/**
	 * @category getStatsForSHC<br>
	 * @param player_id already generated by db
	 * @param competition_id already generated by db
	 * @param lastEvaledHandId already generated by db
	 * @return ArrayList of long[] rounds with:<br>
	 *         round.hand_id, round.id, round.timestamp
	 */
	protected static ArrayList<long[]> getFirstRounds(int player_id, int competition_id, int lastEvaledHandId) {

		ArrayList<long[]> result = h.sqlGetLongArrayListMultiPerRow(GetterQuery.getFirstRounds(player_id, competition_id, lastEvaledHandId), 3);		

		return result;
	}
	
	/**
	 * @category getStatsForFlop<br>
	 * @param player_id already generated by db
	 * @param competition_id already generated by db
	 * @param lastEvaledHandId already generated by db
	 * @return ArrayList of long[] rounds with:<br>
	 *         round.hand_id, round.id, round.timestamp
	 */
	protected static ArrayList<long[]> getFlopRounds(int player_id, int competition_id, int lastEvaledHandId) {

		ArrayList<long[]> result = h.sqlGetLongArrayListMultiPerRow(GetterQuery.getFlopRounds(player_id, competition_id, lastEvaledHandId), 3);		

		return result;
	}


	/**
	 * @category getStatsForSHC<br>
	 * @param round_id already generated by db
	 * @param playersFirstBetId already generated by db
	 * @return long[] PreviousActions with:<br>
	 *         action
	 */
	protected static long[] getPreviousActions(long round_id, long playersFirstBetId) {

		long[] actions = h.sqlGetLongArrayOnePerRow(GetterQuery.getPreviousActions(round_id, playersFirstBetId));

		return actions;
	}


	/**
	 * @category getStatsForSHC<br>
	 * @param player_id already generated by db
	 * @param competition_id already generated by db
	 * @param lastEvaledHandId already generated by db
	 * @return ArrayList of int[] Hands with:<br>
	 *         hand.id, hand.sb, hand.bb, hand.ante, hand.finalpot
	 */
	protected static ArrayList<int[]> getHandsCO(int player_id, int competition_id, int lastEvaledHandId) {

		ArrayList<int[]> handsCO = h.sqlGetIntArrayListMultiPerRow(
				GetterQuery.getHandsCO(player_id, competition_id, lastEvaledHandId), 5);

		return handsCO;
	}
	
	
	/**
	 * @category getStatsForSHC<br>
	 * @param player_id already generated by db
	 * @param competition_id already generated by db
	 * @param lastEvaledHandId already generated by db
	 * @return ArrayList of int[] Hands with:<br>
	 *         hand.id, hand.sb, hand.bb, hand.ante, hand.finalpot
	 */
	protected static ArrayList<int[]> getHandsCC(int player_id, int competition_id, int lastEvaledHandId) {

		ArrayList<int[]> handsCC = h.sqlGetIntArrayListMultiPerRow(
				GetterQuery.getHandsCC(player_id, competition_id, lastEvaledHandId), 5);

		return handsCC;
	}


	/**
	 * @category getStatsForSHC<br>
	 * @param player_id already generated by db
	 * @param competition_id already generated by db
	 * @param lastEvaledHandId already generated by db
	 * @return ArrayList of int[] Hands with:<br>
	 *         hand_player_map for EnemyCardsOpen with:<br>
	 *         hand_player_map.id, hand_player_map.position, hand_player_map.cash_init, hand_player_map.cash_delta, hand_player_map.hand_id
	 */
	protected static ArrayList<int[]> getHandPlayerMapCardsClosed(int player_id, int competition_id, int lastEvaledHandId) {

		ArrayList<int[]> al = h.sqlGetIntArrayListMultiPerRow(GetterQuery.getHandPlayerMapCardsClosed(player_id, competition_id, lastEvaledHandId), 5);

		return al;
	}


	protected static ArrayList<long[]> getRiverRounds(int playerId, int compId, int lastEvaledHandId) {

		ArrayList<long[]> result = h.sqlGetLongArrayListMultiPerRow(GetterQuery.getRiverRounds(playerId, compId, lastEvaledHandId), 3);		

		return result;
	}


	protected static ArrayList<long[]> getRiverBetsOfRound(int playerId, int compId, int lastEvaledHandId) {

		ArrayList<long[]> result = h.sqlGetLongArrayListMultiPerRow(GetterQuery.getRiverBetsOfRound(playerId, compId, lastEvaledHandId), 7);		

		return result;
	}
	
	protected static ArrayList<long[]> getTurnRounds(int playerId, int compId, int lastEvaledHandId) {

		ArrayList<long[]> result = h.sqlGetLongArrayListMultiPerRow(GetterQuery.getTurnRounds(playerId, compId, lastEvaledHandId), 3);		

		return result;
	}


	protected static ArrayList<long[]> getTurnBetsOfRound(int playerId, int compId, int lastEvaledHandId) {

		ArrayList<long[]> result = h.sqlGetLongArrayListMultiPerRow(GetterQuery.getTurnBetsOfRound(playerId, compId, lastEvaledHandId), 7);		

		return result;
	}
}
